using AutoMapper;
using Microsoft.EntityFrameworkCore;
using UwinEducation.Application.Common.Interfaces;
using UwinEducation.Application.Dtos;
using UwinEducation.Domain.Entities;
using UwinEducation.Domain.IRepositories;
using UwinEducation.Infrastructure.Persistence;
using UwinEducation.Shared.Models;

namespace UwinEducation.Application.Services
{
    /// <summary>
    /// 教师服务实现
    /// </summary>
    public class TeacherService : ITeacherService
    {
        private readonly ITeacherRepository _teacherRepository;
        private readonly ITeacherScheduleRepository _teacherScheduleRepository;
        private readonly ITeacherAvailabilityRepository _teacherAvailabilityRepository;
        private readonly ApplicationDbContext _context;
        private readonly IMapper _mapper;

        public TeacherService(
            ITeacherRepository teacherRepository,
            ITeacherScheduleRepository teacherScheduleRepository,
            ITeacherAvailabilityRepository teacherAvailabilityRepository,
            ApplicationDbContext context,
            IMapper mapper
        )
        {
            _teacherRepository = teacherRepository;
            _teacherScheduleRepository = teacherScheduleRepository;
            _teacherAvailabilityRepository = teacherAvailabilityRepository;
            _context = context;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取教师分页列表
        /// </summary>
        public async Task<PagedResult<TeacherDto>> GetPagedListAsync(TeacherPageRequest pageRequest)
        {
            var result = await _teacherRepository.GetPagedListAsync(pageRequest);

            return new PagedResult<TeacherDto>
            {
                Total = result.Total,
                Items = _mapper.Map<List<TeacherDto>>(result.Items)
            };
        }

        /// <summary>
        /// 获取教师分页列表（按是否有排课排序）
        /// </summary>
        public async Task<PagedResult<TeacherDto>> GetPagedListWithScheduleStatusAsync(TeacherAvailabilityPageRequest pageRequest)
        {
            // 先查询有档期的教师ID
            var availabilityQuery = _context.TeacherAvailabilities
                .Where(ta => !ta.IsDeleted);
            
            // 应用档期筛选条件
            if (pageRequest.StartDate.HasValue && pageRequest.EndDate.HasValue)
            {
                availabilityQuery = availabilityQuery.Where(ta => 
                    ta.StartDate <= pageRequest.EndDate.Value && 
                    ta.EndDate >= pageRequest.StartDate.Value);
            }
            
            // 获取有档期的教师ID
            var teachersWithAvailability = await availabilityQuery
                .Select(ta => ta.TeacherId)
                .Distinct()
                .ToListAsync();
            
            var teachersWithAvailabilitySet = new HashSet<Guid>(teachersWithAvailability);
            
            // 只查询有档期的教师
            var query = _context.Teachers
                .Where(t => !t.IsDeleted && teachersWithAvailabilitySet.Contains(t.Id));
            
            // 应用教师筛选条件
            if (pageRequest.TeacherId.HasValue)
            {
                query = query.Where(t => t.Id == pageRequest.TeacherId);
            }
            if (!string.IsNullOrEmpty(pageRequest.TeacherNo))
            {
                query = query.Where(t => t.TeacherNo.Contains(pageRequest.TeacherNo));
            }
            if (!string.IsNullOrEmpty(pageRequest.Name))
            {
                query = query.Where(t => t.Name.Contains(pageRequest.Name));
            }
            if (!string.IsNullOrEmpty(pageRequest.Phone))
            {
                query = query.Where(t => t.Phone.Contains(pageRequest.Phone));
            }
            if (!string.IsNullOrEmpty(pageRequest.Email))
            {
                query = query.Where(t => t.Email.Contains(pageRequest.Email));
            }
            if (!string.IsNullOrEmpty(pageRequest.Remarks))
            {
                query = query.Where(t => t.Remarks.Contains(pageRequest.Remarks));
            }
            
            // 计算总记录数
            var total = await query.CountAsync();
            
            // 查询哪些教师有排课
            var scheduleQuery = _context.TeacherSchedules
                .Where(ts => teachersWithAvailabilitySet.Contains(ts.TeacherId) && 
                        ts.Status == UwinEducation.Shared.Enums.ScheduleStatus.Normal);
            
            // 应用排课筛选条件
            if (pageRequest.StartDate.HasValue && pageRequest.EndDate.HasValue)
            {
                scheduleQuery = scheduleQuery.Where(ts => 
                    ts.StartTime <= pageRequest.EndDate.Value && 
                    ts.EndTime >= pageRequest.StartDate.Value);
            }
            
            var teachersWithSchedule = await scheduleQuery
                .Select(ts => ts.TeacherId)
                .Distinct()
                .ToListAsync();
            
            var teachersWithScheduleSet = new HashSet<Guid>(teachersWithSchedule);
            
            // 获取所有符合条件的教师
            var teachers = await query
                .OrderBy(t => t.TeacherNo)
                .ToListAsync();
            
            // 创建DTO并设置状态标志
            var teacherDtos = teachers.Select(teacher => {
                var dto = _mapper.Map<TeacherDto>(teacher);
                dto.HasAvailability = true; // 已经过滤，所有教师都有档期
                dto.HasSchedule = teachersWithScheduleSet.Contains(teacher.Id);
                return dto;
            }).ToList();
            
            // 排序：优先显示没有排课的教师
            var sortedTeacherDtos = teacherDtos
                .OrderBy(dto => dto.HasSchedule) // 没有排课的排前面
                .ThenBy(dto => dto.TeacherNo)
                .Skip((pageRequest.PageIndex - 1) * pageRequest.PageSize)
                .Take(pageRequest.PageSize)
                .ToList();
            
            return new PagedResult<TeacherDto>
            {
                Total = total,
                Items = sortedTeacherDtos
            };
        }

        /// <summary>
        /// 获取教师详情
        /// </summary>
        public async Task<TeacherDto> GetByIdAsync(Guid id)
        {
            var teacher = await _teacherRepository.GetDetailsByIdAsync(id);
            if (teacher == null)
            {
                throw new ArgumentException($"教师不存在: {id}");
            }

            return _mapper.Map<TeacherDto>(teacher);
        }

        /// <summary>
        /// 创建教师
        /// </summary>
        public async Task<TeacherDto> CreateAsync(CreateTeacherDto input)
        {
            // 检查工号是否已存在
            if (await _teacherRepository.ExistsByTeacherNoAsync(input.TeacherNo))
            {
                throw new ArgumentException($"教师工号已存在: {input.TeacherNo}");
            }

            var teacher = Teacher.Create(
                input.TeacherNo,
                input.Name,
                input.Phone ?? string.Empty,
                input.Email ?? string.Empty,
                input.Remarks ?? string.Empty,
                input.FirstName ?? string.Empty,
                input.Surname ?? string.Empty,
                input.ABN ?? string.Empty,
                input.TFN ?? string.Empty,
                input.HomeAddress ?? string.Empty,
                input.DOB ?? string.Empty,
                input.BackupTFN ?? string.Empty,
                input.BankDetail ?? string.Empty,
                input.WWCCNumber ?? string.Empty,
                input.ExpireDate, // 直接传递，如果为 null 则不设置
                input.AccountNumber ?? string.Empty,
                input.OneToOnePrice ?? 0,
                input.OneToTwoPrice ?? 0,
                input.OneToThreePrice ?? 0,
                input.OneToFourPrice ?? 0,
                input.OneToFivePrice ?? 0,
                input.OneToSixPrice ?? 0
            );

            await _teacherRepository.AddAsync(teacher);
            return _mapper.Map<TeacherDto>(teacher);
        }

        /// <summary>
        /// 更新教师
        /// </summary>
        public async Task<TeacherDto> UpdateAsync(UpdateTeacherDto input)
        {
            var teacher = await _teacherRepository.GetByIdAsync(input.Id);
            if (teacher == null)
            {
                throw new ArgumentException($"教师不存在: {input.Id}");
            }

            // 检查工号是否已被其他教师使用
            if (await _teacherRepository.ExistsByTeacherNoAsync(input.TeacherNo, input.Id))
            {
                throw new ArgumentException($"教师工号已存在: {input.TeacherNo}");
            }

            teacher.TeacherNo = input.TeacherNo;
            teacher.Name = input.Name;
            teacher.Phone = input.Phone ?? teacher.Phone;
            teacher.Email = input.Email ?? teacher.Email;
            teacher.Remarks = input.Remarks ?? teacher.Remarks;
            teacher.FirstName = input.FirstName ?? teacher.FirstName;
            teacher.Surname = input.Surname ?? teacher.Surname;
            teacher.ABN = input.ABN ?? teacher.ABN;
            teacher.TFN = input.TFN ?? teacher.TFN;
            teacher.HomeAddress = input.HomeAddress ?? teacher.HomeAddress;
            teacher.DOB = input.DOB ?? teacher.DOB;
            teacher.BackupTFN = input.BackupTFN ?? teacher.BackupTFN;
            teacher.BankDetail = input.BankDetail ?? teacher.BankDetail;
            teacher.WWCCNumber = input.WWCCNumber ?? teacher.WWCCNumber;

            teacher.AccountNumber = input.AccountNumber ?? teacher.AccountNumber;
            teacher.OneToOnePrice = input.OneToOnePrice ?? teacher.OneToOnePrice ?? 0;
            teacher.OneToTwoPrice = input.OneToTwoPrice ?? teacher.OneToTwoPrice ?? 0;
            teacher.OneToThreePrice = input.OneToThreePrice ?? teacher.OneToThreePrice ?? 0;
            teacher.OneToFourPrice = input.OneToFourPrice ?? teacher.OneToFourPrice ?? 0;
            teacher.OneToFivePrice = input.OneToFivePrice ?? teacher.OneToFivePrice ?? 0;
            teacher.OneToSixPrice = input.OneToSixPrice ?? teacher.OneToSixPrice ?? 0;

            // 只有当 ExpireDate 有值时才更新
            if (input.ExpireDate.HasValue)
            {
                teacher.ExpireDate = input.ExpireDate;
            }

            await _teacherRepository.UpdateAsync(teacher);
            return _mapper.Map<TeacherDto>(teacher);
        }

        /// <summary>
        /// 删除教师
        /// </summary>
        public async Task DeleteAsync(Guid id)
        {
            // 检查TeacherSchedule是否存在
            var teacherSchedules = await _teacherScheduleRepository.GetByTeacherIdAsync(id);
            if (teacherSchedules.Any())
            {
                throw new ArgumentException($"教师: {teacherSchedules.First().Teacher.Name} 存在老师课程，不能删除");
            }

            var teacher = await _teacherRepository.GetByIdAsync(id);
            if (teacher == null)
            {
                throw new ArgumentException($"教师不存在: {id}");
            }

            await _teacherRepository.DeleteAsync(id);
        }
    }
}